home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter25 / isohex25_3 / isohex25_3.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-15  |  11.1 KB  |  461 lines

  1. /*****************************************************************************
  2. IsoHex24_3.cpp
  3. Ernest S. Pazera
  4. 14DEC2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Needs ddraw.lib, d3d8.lib and dxguid.lib
  7. Needs GDICanvas.h/cpp
  8. Needs DDFuncs.h/cpp
  9. Needs D3DFuncs.h/cpp
  10. *****************************************************************************/
  11.  
  12. //////////////////////////////////////////////////////////////////////////////
  13. //INCLUDES
  14. //////////////////////////////////////////////////////////////////////////////
  15. #define WIN32_LEAN_AND_MEAN  
  16.  
  17. #include <windows.h>   
  18. #include <math.h>//sin and cos
  19. #include "GDICanvas.h"
  20. #include "ddraw.h"
  21. #include "DDFuncs.h"
  22. #include "d3d.h"
  23. #include "d3dfuncs.h"
  24.  
  25. //////////////////////////////////////////////////////////////////////////////
  26. //DEFINES
  27. //////////////////////////////////////////////////////////////////////////////
  28. //name for our window class
  29. #define WINDOWCLASS "ISOHEX25"
  30. //title of the application
  31. #define WINDOWTITLE "IsoHex 25-3"
  32.  
  33. //screen attributes
  34. const DWORD SCREENWIDTH=640;
  35. const DWORD SCREENHEIGHT=480;
  36. const DWORD SCREENBPP=16;
  37.  
  38. //tile dimensions
  39. const DWORD TILEWIDTH=64;
  40. const DWORD TILEHEIGHT=32;
  41.  
  42. //map dimensions
  43. const DWORD MAPWIDTH=20;
  44. const DWORD MAPHEIGHT=40;
  45.  
  46. //////////////////////////////////////////////////////////////////////////////
  47. //PROTOTYPES
  48. //////////////////////////////////////////////////////////////////////////////
  49. bool Prog_Init();//game data initalizer
  50. void Prog_Loop();//main game loop
  51. void Prog_Done();//game clean up
  52.  
  53. //////////////////////////////////////////////////////////////////////////////
  54. //GLOBALS
  55. //////////////////////////////////////////////////////////////////////////////
  56. HINSTANCE hInstMain=NULL;//main application handle
  57. HWND hWndMain=NULL;//handle to our main window
  58.  
  59. //IDirectDraw7 Pointer
  60. LPDIRECTDRAW7 lpdd=NULL;
  61.  
  62. //surfaces
  63. LPDIRECTDRAWSURFACE7 lpddsPrime=NULL;
  64. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  65. LPDIRECTDRAWSURFACE7 lpddsTexture=NULL;
  66. LPDIRECTDRAWSURFACE7 lpddsSprite=NULL;
  67.  
  68. //IDirect3D7
  69. LPDIRECT3D7 lpd3d=NULL;
  70.  
  71. //IDirect3DDevice
  72. LPDIRECT3DDEVICE7 lpd3ddev=NULL;
  73.  
  74. //vertices
  75. D3DTLVERTEX vert[4];//the vertices
  76. D3DTLVERTEX spritevert[4];//sprite vertices
  77.  
  78. //////////////////////////////////////////////////////////////////////////////
  79. //WINDOWPROC
  80. //////////////////////////////////////////////////////////////////////////////
  81. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  82. {
  83.     //which message did we get?
  84.     switch(uMsg)
  85.     {
  86.     case WM_KEYDOWN:
  87.         {
  88.             //check for escape key
  89.             if(wParam==VK_ESCAPE)
  90.             {
  91.                 DestroyWindow(hWndMain);
  92.             }
  93.  
  94.             return(0);//handled message
  95.         }break;
  96.     case WM_DESTROY://the window is being destroyed
  97.         {
  98.  
  99.             //tell the application we are quitting
  100.             PostQuitMessage(0);
  101.  
  102.             //handled message, so return 0
  103.             return(0);
  104.  
  105.         }break;
  106.     case WM_PAINT://the window needs repainting
  107.         {
  108.             //a variable needed for painting information
  109.             PAINTSTRUCT ps;
  110.             
  111.             //start painting
  112.             HDC hdc=BeginPaint(hwnd,&ps);
  113.  
  114.             /////////////////////////////
  115.             //painting code would go here
  116.             /////////////////////////////
  117.  
  118.             //end painting
  119.             EndPaint(hwnd,&ps);
  120.                         
  121.             //handled message, so return 0
  122.             return(0);
  123.         }break;
  124.     }
  125.  
  126.     //pass along any other message to default message handler
  127.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  128. }
  129.  
  130.  
  131. //////////////////////////////////////////////////////////////////////////////
  132. //WINMAIN
  133. //////////////////////////////////////////////////////////////////////////////
  134. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  135. {
  136.     //assign instance to global variable
  137.     hInstMain=hInstance;
  138.  
  139.     //create window class
  140.     WNDCLASSEX wcx;
  141.  
  142.     //set the size of the structure
  143.     wcx.cbSize=sizeof(WNDCLASSEX);
  144.  
  145.     //class style
  146.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  147.  
  148.     //window procedure
  149.     wcx.lpfnWndProc=TheWindowProc;
  150.  
  151.     //class extra
  152.     wcx.cbClsExtra=0;
  153.  
  154.     //window extra
  155.     wcx.cbWndExtra=0;
  156.  
  157.     //application handle
  158.     wcx.hInstance=hInstMain;
  159.  
  160.     //icon
  161.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  162.  
  163.     //cursor
  164.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  165.  
  166.     //background color
  167.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  168.  
  169.     //menu
  170.     wcx.lpszMenuName=NULL;
  171.  
  172.     //class name
  173.     wcx.lpszClassName=WINDOWCLASS;
  174.  
  175.     //small icon
  176.     wcx.hIconSm=NULL;
  177.  
  178.     //register the window class, return 0 if not successful
  179.     if(!RegisterClassEx(&wcx)) return(0);
  180.  
  181.     //create main window
  182.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  183.  
  184.     //error check
  185.     if(!hWndMain) return(0);
  186.  
  187.     //if program initialization failed, then return with 0
  188.     if(!Prog_Init()) return(0);
  189.  
  190.     //message structure
  191.     MSG msg;
  192.  
  193.     //message pump
  194.     for(;;)    
  195.     {
  196.         //look for a message
  197.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  198.         {
  199.             //there is a message
  200.  
  201.             //check that we arent quitting
  202.             if(msg.message==WM_QUIT) break;
  203.             
  204.             //translate message
  205.             TranslateMessage(&msg);
  206.  
  207.             //dispatch message
  208.             DispatchMessage(&msg);
  209.         }
  210.  
  211.         //run main game loop
  212.         Prog_Loop();
  213.     }
  214.     
  215.     //clean up program data
  216.     Prog_Done();
  217.  
  218.     //return the wparam from the WM_QUIT message
  219.     return(msg.wParam);
  220. }
  221.  
  222. HRESULT CALLBACK TextureFormatCallback(LPDDPIXELFORMAT lpDDPF,LPVOID lpContext)
  223. {
  224.     //check the alpha bitmask of the pixel format
  225.     if(lpDDPF->dwRGBAlphaBitMask)
  226.     {
  227.         //alpha
  228.         //copy to context
  229.         memcpy(lpContext,lpDDPF,sizeof(DDPIXELFORMAT));
  230.         //stop enumeration
  231.         return(D3DENUMRET_CANCEL);
  232.     }
  233.     //no alpha found
  234.     //continue enumeration
  235.     return(D3DENUMRET_OK);
  236. }
  237.  
  238.  
  239. //////////////////////////////////////////////////////////////////////////////
  240. //INITIALIZATION
  241. //////////////////////////////////////////////////////////////////////////////
  242. bool Prog_Init()
  243. {
  244.     lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
  245.  
  246.     //set the display mode
  247.     lpdd->SetDisplayMode(SCREENWIDTH,SCREENHEIGHT,SCREENBPP,0,0);
  248.  
  249.     //create primary surface
  250.     lpddsPrime=LPDDS_CreatePrimary3D(lpdd,1);
  251.  
  252.     //create back buffer
  253.     lpddsBack=LPDDS_GetSecondary3D(lpddsPrime);
  254.     
  255.     //get the idirect3d pointer
  256.     lpd3d=LPD3D_Create(lpdd);
  257.  
  258.     //create the idirect3ddevice(hack method)
  259.     lpd3ddev=LPD3DDEV_Create(lpd3d,lpddsBack);
  260.  
  261.     //set up viewport
  262.     LPD3DDEV_SetViewport(lpd3ddev,0,0,SCREENWIDTH,SCREENHEIGHT);
  263.  
  264.     //load in texture image
  265.     CGDICanvas gdic;
  266.     gdic.Load(NULL,"texture.bmp");
  267.  
  268.     //load texture
  269.     lpddsTexture=LPDDS_CreateTexture(lpdd,gdic.GetWidth(),gdic.GetHeight());
  270.  
  271.     //grab texture's DC
  272.     HDC hdc;
  273.     lpddsTexture->GetDC(&hdc);
  274.  
  275.     //blit image
  276.     BitBlt(hdc,0,0,gdic.GetWidth(),gdic.GetHeight(),gdic,0,0,SRCCOPY);
  277.  
  278.     //release texture's dc
  279.     lpddsTexture->ReleaseDC(hdc);
  280.  
  281.  
  282. //START LOADING SPRITE
  283.     //clear out pixel format
  284.     DDPIXELFORMAT ddpf;
  285.     memset(&ddpf,0,sizeof(DDPIXELFORMAT));
  286.  
  287.     //enumerate texture formats
  288.     lpd3ddev->EnumTextureFormats(TextureFormatCallback,&ddpf);
  289.  
  290.     //load in the sprite
  291.     gdic.Load(NULL,"unit_warrior.bmp");
  292.  
  293.     //determine transparent color
  294.     COLORREF crTransparent=GetPixel(gdic,gdic.GetWidth()-1,gdic.GetHeight()-1);
  295.     //colors for later
  296.     COLORREF crColor;
  297.     DWORD ddColor;
  298.     //tex width and height
  299.     int TexWidth=gdic.GetWidth()-1;
  300.     int TexHeight=gdic.GetHeight()-1;
  301.  
  302.     //find the anchor
  303.     POINT ptAnchor;
  304.     int x;
  305.     int y;
  306.  
  307.     //find horizontal anchor
  308.     for(x=0;x<TexWidth;x++)
  309.     {
  310.         if(GetPixel(gdic,x,TexHeight)!=crTransparent)
  311.         {
  312.             //found anchor
  313.             ptAnchor.x=x;
  314.             break;
  315.         }
  316.     }
  317.  
  318.     //find vert anchor
  319.     for(y=0;y<TexHeight;y++)
  320.     {
  321.         if(GetPixel(gdic,TexWidth,y)!=crTransparent)
  322.         {
  323.             //found anchor
  324.             ptAnchor.y=y;
  325.             break;
  326.         }
  327.     }
  328.  
  329.     //set up vertices
  330.     VERTEX_Set(&spritevert[0],-ptAnchor.x,-ptAnchor.y,D3DRGB(1.0,1.0,1.0),0.0,0.0);
  331.     VERTEX_Set(&spritevert[1],-ptAnchor.x+TexWidth,-ptAnchor.y,D3DRGB(1.0,1.0,1.0),1.0,0.0);
  332.     VERTEX_Set(&spritevert[2],-ptAnchor.x,-ptAnchor.y+TexHeight,D3DRGB(1.0,1.0,1.0),0.0,1.0);
  333.     VERTEX_Set(&spritevert[3],-ptAnchor.x+TexWidth,-ptAnchor.y+TexHeight,D3DRGB(1.0,1.0,1.0),1.0,1.0);
  334.  
  335.     //create sprite texture
  336.     lpddsSprite=LPDDS_CreateTexturePixelFormat(lpdd,TexWidth,TexHeight,&ddpf);
  337.  
  338.     //lock texture
  339.     DDSURFACEDESC2 ddsd;
  340.     DDSD_Clear(&ddsd);
  341.     lpddsSprite->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL);
  342.  
  343.     //grab pitch and surface pointer
  344.     LONG lPitch=ddsd.lPitch/sizeof(WORD);
  345.     WORD* pSurface=(WORD*)ddsd.lpSurface;
  346.  
  347.     //loop through pixels
  348.     for(x=0;x<TexWidth;x++)
  349.     {
  350.         for(y=0;y<TexHeight;y++)
  351.         {
  352.             //grab color
  353.             crColor=GetPixel(gdic,x,y);
  354.             //convert
  355.             ddColor=ConvertColorRef(crColor,&ddpf);
  356.             //check transparency
  357.             if(crColor!=crTransparent)
  358.             {
  359.                 //add alpha value
  360.                 ddColor|=ddpf.dwRGBAlphaBitMask;
  361.             }
  362.             //place pixel
  363.             pSurface[x+y*lPitch]=ddColor;
  364.         }
  365.     }
  366.  
  367.     //unlock texture
  368.     lpddsSprite->Unlock(NULL);
  369.  
  370.     //set the render states
  371.     lpd3ddev->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE,TRUE);
  372.     lpd3ddev->SetRenderState(D3DRENDERSTATE_ALPHAREF,0x7F);
  373.     lpd3ddev->SetRenderState(D3DRENDERSTATE_ALPHAFUNC,D3DCMP_GREATER);
  374.  
  375. //END LOADING SPRITE
  376.  
  377.     //position sprite for center of the screen
  378.     for(int count=0;count<4;count++)
  379.     {
  380.         spritevert[count].sx+=320.0;
  381.         spritevert[count].sy+=240.0;
  382.     }
  383.  
  384.     return(true);//return success
  385. }
  386.  
  387. //////////////////////////////////////////////////////////////////////////////
  388. //CLEANUP
  389. //////////////////////////////////////////////////////////////////////////////
  390. void Prog_Done()
  391. {    
  392.     //release textures
  393.     LPDDS_Release(&lpddsSprite);
  394.     LPDDS_Release(&lpddsTexture);
  395.  
  396.     //release IDirect3DDevice
  397.     LPD3DDEV_Release(&lpd3ddev);
  398.  
  399.     //release IDirect3D 
  400.     LPD3D_Release(&lpd3d);
  401.  
  402.     //clean up primary surface(this will clean up the back buffer, also)
  403.     LPDDS_Release(&lpddsPrime);
  404.  
  405.     //clean up the dd pointer
  406.     LPDD_Release(&lpdd);
  407. }
  408.  
  409. //////////////////////////////////////////////////////////////////////////////
  410. //MAIN GAME LOOP
  411. //////////////////////////////////////////////////////////////////////////////
  412. void Prog_Loop()
  413. {
  414.     //clear the viewport to black
  415.     lpd3ddev->Clear(0,NULL,D3DCLEAR_TARGET,0,0,0);
  416.  
  417.     //start the scene
  418.     lpd3ddev->BeginScene();
  419.  
  420.     //set texture for tile
  421.     lpd3ddev->SetTexture(0,lpddsTexture);
  422.  
  423.     //center positions
  424.     D3DVALUE CenterX,CenterY;
  425.  
  426.     //loop through map
  427.     for(int y=0;y<MAPHEIGHT;y++)
  428.     {
  429.         for(int x=0;x<MAPWIDTH;x++)
  430.         {
  431.             //calculate world coordinates for center of tile
  432.             CenterX=(float)(x*TILEWIDTH+(y&1)*(TILEWIDTH/2));
  433.             CenterY=(float)(y*(TILEHEIGHT/2));
  434.  
  435.             //set up the vertex
  436.             //v1
  437.             VERTEX_Set(&vert[0],CenterX-TILEWIDTH/2,CenterY,D3DRGB(1.0,1.0,1.0),0.0,0.0);
  438.             //v2
  439.             VERTEX_Set(&vert[1],CenterX,CenterY-TILEHEIGHT/2,D3DRGB(1.0,1.0,1.0),1.0,0.0);
  440.             //v3
  441.             VERTEX_Set(&vert[2],CenterX,CenterY+TILEHEIGHT/2,D3DRGB(1.0,1.0,1.0),0.0,1.0);
  442.             //v4
  443.             VERTEX_Set(&vert[3],CenterX+TILEWIDTH/2,CenterY,D3DRGB(1.0,1.0,1.0),1.0,1.0);
  444.  
  445.             //render the triangle strip
  446.             LPD3DDEV_DrawTriangleStrip(lpd3ddev,vert,4);
  447.         }
  448.     }
  449.  
  450.     //place sprite
  451.     lpd3ddev->SetTexture(0,lpddsSprite);
  452.     LPD3DDEV_DrawTriangleStrip(lpd3ddev,spritevert,4);
  453.  
  454.     //end the scene
  455.     lpd3ddev->EndScene();
  456.  
  457.     //flip 
  458.     lpddsPrime->Flip(NULL,DDFLIP_WAIT);
  459. }
  460.  
  461.